from abc import ABC, abstractmethod

from src.json_patch import JSONPatch, StatusPatch
from .mimo import MimoProcessor, MimoStatus

DecodeBitStream = tuple[int, int, int, int]


class MimoDecodeProcessor(MimoProcessor):
    """
    预期消息体格式:
    ```jsonc
    {
        "id": 1,    // 报告 ID
        "args": {
            "index": 1,             // int   >= 0       数组序号
            "receiveAntennas": 2,   // int   > 1        接收天线数
            "modulationMode": 1,    // int   [1 ~ 3]    调制方式
            "noiseRate": 0.1,       // float [-10 ~ 20] 信噪比
            "bitStream": 15,        // int   [0 ~ 15]   比特流
        },
    }
    ```
    预期响应`body.data`
    ```jsonc
    [{
        "op": "add",
        "path": "/decode/1/result",
        "value": 15,
    }]
    ```
    """

    def __init__(self, body: bytes) -> None:
        super().__init__(body)

        self.index: int = self.args["index"]
        bit_stream_int = self.args["bitStream"]
        # 比特流存储与传输时使用十进制 int 类型, 但在计算时使用二进制 tuple[int, int, int, int] 类型
        self.bit_stream: DecodeBitStream = self._int_to_binary_tuple(bit_stream_int)

    def build_data(self, decodeResult: DecodeBitStream):
        return JSONPatch().add_patch(
            "add",
            "/decode/" + str(self.index) + "/result",
            self._binary_tuple_to_int(decodeResult),
        )

    def get_success_status_patch(self) -> StatusPatch:
        return StatusPatch().add_patch("remove", MimoStatus.DECODING.value)

    def _binary_tuple_to_int(self, res_tuple: DecodeBitStream):
        return int("".join(str(b) for b in res_tuple), 2)

    def _int_to_binary_tuple(self, res) -> tuple[int, int, int, int]:
        return tuple(int(b) for b in bin(res)[2:].zfill(4))  # type: ignore


class MimoDecodeAdaptor(ABC):
    @abstractmethod
    def mimo_decode(self, processor: MimoDecodeProcessor) -> DecodeBitStream: ...
